package com.tm.controller;

import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import com.googlecode.objectify.Key;
import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyService;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;
import com.tm.fundament.Initializer;
import com.tm.pojo.Price;
import com.tm.pojo.PriceDate;

public class PriceController {
	private static PriceController pc = null;
	private Long instrumentId = null;
	private List<Price> prices = new Vector<Price>();
	private boolean isInitialized = false;
	
	private PriceController() {
		Initializer.getInstance().init();
	}
	
	private void init() {
		loadStoredPrices();
		isInitialized = true;
	}
	
	public static PriceController getInstance() {
		if (pc == null) {
			pc = new PriceController();
		}
		return pc;
	}
	
	public Long getInstrumentId() {
		return instrumentId;
	}
	
	public void setInstrumentId(Long instrumentId) {
		if (this.instrumentId != null && !this.instrumentId.equals(instrumentId)) {
			isInitialized = false;
			prices.clear();
		}
		this.instrumentId = instrumentId;
	}
	
	private void loadStoredPrices() {
		prices.clear();
		Query q = new Query("Price");
		q.addSort("date", Query.SortDirection.DESCENDING);
		q.addFilter("instrumentId", Query.FilterOperator.EQUAL, instrumentId);
		Objectify ofy = ObjectifyService.begin();
		PreparedQuery pq = ofy.getDatastore().prepare(q);
		List<Entity> l = pq.asList(FetchOptions.Builder.withDefaults());
		Iterator<Entity> i = l.iterator();
		while (i.hasNext()) {
			Entity e = i.next();
			Price p = new Price(e);
			prices.add(p);
		}
	}
	
	public List<Price> getPrices() {
		if (isInitialized == false) {
			init();
		}
		return prices;
	}
	
	public Price saveNewPrice(Price p) {
		if (isInitialized == false) {
			init();
		}
		Objectify ofy = ObjectifyService.begin();
		p.setInstrumentId(instrumentId);
		ofy.put(p);
		prices.add(p);
		Collections.sort(prices);
		return p;
	}
	
	public PriceDate getLastPrice() {
		if (isInitialized) {
			if (prices.size() > 0) {
				return(new PriceDate(prices.get(prices.size()-1)));
			} else {
				return new PriceDate();
			}
		} else {
			Query q = new Query("Price");
			q.addSort("date", Query.SortDirection.DESCENDING);
			q.addFilter("instrumentId", Query.FilterOperator.EQUAL, instrumentId);
			Objectify ofy = ObjectifyService.begin();
			PreparedQuery pq = ofy.getDatastore().prepare(q);
			List<Entity> l = pq.asList(FetchOptions.Builder.withLimit(1));
			if (l.size() == 0) {
				return new PriceDate();
			} else {
				PriceDate pd = new PriceDate();
				pd.setDate((Date)l.get(0).getProperties().get("date"));
				pd.setPrice((Double)l.get(0).getProperties().get("price"));
				return (pd);
			}
		}
	}
	
	public void deletePrice(String strPriceId) {
		if (strPriceId != null && strPriceId.trim().length()>0) {
			try {
				Long priceId = Long.parseLong(strPriceId);
				Objectify ofy = ObjectifyService.begin();
				Key<Price> k = new Key<Price>(Price.class, priceId);
				Price p = ofy.get(k);
				if (p!=null) {
					ofy.delete(k);
					prices.remove(p);
				}
			} catch (Throwable e) {
				// ignore
			}
		}
	}

}
